JBoss Community Archive (Read Only)

JBoss OSGi

Arquillian Test Framework

Overview

Arquillian is a Test Framework that allows you to run plain JUnit4 test cases from within an OSGi Framework. That the test is actually executed in the the OSGi Framework is transparent to your test case. There is no requirement to extend a specific base class. Your OSGi tests execute along side with all your other (non OSGi specific) test cases in Maven, Ant, or Eclipse.

Some time ago I was looking for ways to test bundles that are deployed to a remote instance of the JBoss OSGi Runtime. I wanted the solution to also work with an OSGi Framework that is bootstrapped from within a JUnit test case.

The basic problem is of course that you cannot access the artefacts that you deploy in a bundle directly from your test case, because they are loaded from different classloaders.

images/author/download/attachments/4784853/arquillian-problem.png

For this release, we extended the Arquillian Test Framework to provide support for these requirements.

  • Test cases SHOULD be plain JUnit4 POJOs

  • There SHOULD be no requirement to extend a specific test base class

  • There MUST be no requirement on a specific test runner (i.e. MUST run with Maven)

  • There SHOULD be a minimum test framework leakage into the test case

  • The test framework MUST support embedded and remote OSGi runtimes with no change required to the test

  • The same test case MUST be executable from outside as well as from within the OSGi Framework

  • There SHOULD be a pluggable communication layer from the test runner to the OSGi Framework

  • The test framework MUST NOT depend on OSGi Framework specific features

  • There MUST be no automated creation of test bundles required by the test framework

Configuration

In the target OSGi Framework, you need to have the arquillian-osgi-bundle.jar up and running. For remote testing you also need jboss-osgi-jmx.jar because Arquillian uses the a standard JSR-160 to communicate between the test client and the remote OSGi Framework.

See jboss-osgi-jmx on how the JMX protocol can be configured.

Writing Arquillian Tests

In an Arquillian test you

  • need to use the @RunWith(Arquillian.class) test runner

  • may have a @Deployment method that generates the test bundle

  • may have @Inject BundleContext to get the system BundleContext injected

  • may have @Inject Bundle to get the test bundle injected

@RunWith(Arquillian.class)
public class SimpleArquillianTestCase
{
   @Inject
   public Bundle bundle;
   
   @Deployment
   public static JavaArchive createdeployment()
   {
      final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "example-arquillian");
      archive.addClasses(SimpleActivator.class, SimpleService.class);
      archive.setManifest(new Asset()
      {
         public InputStream openStream()
         {
            OSGiManifestBuilder builder = OSGiManifestBuilder.newInstance();
            builder.addBundleSymbolicName(archive.getName());
            builder.addBundleManifestVersion(2);
            builder.addBundleActivator(SimpleActivator.class.getName());
            return builder.openStream();
         }
      });
      return archive;
   }
   
   @Test
   public void testBundleInjection() throws Exception
   {
      // Assert that the bundle is injected
      assertNotNull("Bundle injected", bundle);
      
      // Assert that the bundle is in state RESOLVED
      // Note when the test bundle contains the test case it 
      // must be resolved already when this test method is called
      assertEquals("Bundle RESOLVED", Bundle.RESOLVED, bundle.getState());
      
      // Start the bundle
      bundle.start();
      assertEquals("Bundle ACTIVE", Bundle.ACTIVE, bundle.getState());
      
      // Get the service reference
      BundleContext context = bundle.getBundleContext();
      ServiceReference sref = context.getServiceReference(SimpleService.class.getName());
      assertNotNull("ServiceReference not null", sref);
      
      // Get the service for the reference
      SimpleService service = (SimpleService)context.getService(sref);
      assertNotNull("Service not null", service);
      
      // Invoke the service 
      int sum = service.sum(1, 2, 3);
      assertEquals(6, sum);
      
      // Stop the bundle
      bundle.stop();
      assertEquals("Bundle RESOLVED", Bundle.RESOLVED, bundle.getState());
   }
}
JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-11 11:34:49 UTC, last content change 2012-03-07 10:11:01 UTC.